package com.navy.chen.tetrisgame.dao;

import android.util.Log;

import com.navy.chen.tetrisgame.bean.Tetris;
import com.navy.chen.tetrisgame.tool.Config;
import com.navy.chen.tetrisgame.tool.Tools;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/12/14.
 */
public class TetrisDao {
    private final String TAG = Config.TAG + getClass().getSimpleName();
    private int[][] container = new int[Config.getInstance().heght_num][Config.getInstance().width_num];



    public TetrisDao() {
        init();
    }

    private void init(){
        for (int i = 0; i < container.length; i++) {
            for (int j = 0; j < container[0].length; j++) {
                container[i][j] = 0;
            }
        }
    }
    public boolean down(Tetris tetris){
        int relativeX = tetris.getRelativeX(Config.getInstance().getSideLength());
        int relativeY = tetris.getRelativeY(Config.getInstance().getSideLength());
        if (canDrawInBg(relativeX, relativeY+1, tetris.getMatrix(), 0)){
            Log.d(TAG, String.format("tetris 原来的y=%f",tetris.getY()));
            tetris.setY(Config.getInstance().getSideLength() + tetris.getY());
            Log.d(TAG, String.format("tetris 现在的y=%f", tetris.getY()));
            return true;
            //drawTetrisListener.drawTetris(tetris);
        } else {
            fillTetrisToContainer(relativeX, relativeY, tetris.getMatrix());
            Log.d(TAG, String.format("tetris metris==================="));
            Tools.print(container);
            return false;
        }
    }

    public boolean move(Tetris tetris, int direction){
        if (tetris.getMatrix() == null){
            return false;
        }
        int relativeX = tetris.getRelativeX(Config.getInstance().getSideLength());
        int relativeY = tetris.getRelativeY(Config.getInstance().getSideLength());
        Log.d(TAG, String.format("tetris x=%f", tetris.getX()/Config.getInstance().getSideLength()));
        Log.d(TAG, String.format("relativeX=%d", relativeX));
        if (canDrawInBg(relativeX+direction, relativeY, tetris.getMatrix(), direction)){
            tetris.setX(tetris.getX() + Config.getInstance().getSideLength() * direction);
           // drawTetrisListener.drawTetris(tetris);
            return true;
        } else {
            return false;
        }
    }

    public boolean rotate(Tetris tetris, int direction){
        if (tetris.getMatrix() == null){
            return false;
        }
        int result[][] ;
        if (direction == Tetris.RIGHT){
             result= Tools.rotateMatrixRight(tetris.getMatrix());
        } else {
            result = Tools.rotateMatrixLeft(tetris.getMatrix());
        }
        if (result== null){
            return false;
        }
        int relativeX = tetris.getRelativeX(Config.getInstance().getSideLength());
        int relativeY = tetris.getRelativeY(Config.getInstance().getSideLength());

        if (canDrawInBg(relativeX, relativeY, result)){
            tetris.setMatrix(result);
            //drawTetrisListener.drawTetris(tetris);
            return true;
        } else {
            return false;
        }
    }
    private boolean canDrawInBg(int relativeX, int relativeY, int[][] result){
        return canDrawInBg(relativeX, relativeY, result, 0);
    }

    private boolean canDrawInBg(int relativeX, int relativeY, int[][] result, int direction){
        /**
         * 1.判断边界问题  左边界 右边界
         * 2.判断旋转矩阵 有内容的点（为1的点） 对应的container是否为0
         */
        //俄罗斯方块的起始坐标不变
        int blankLeft = Tools.getBlankLeft(result);
        int blankTop = Tools.getBlankTop(result);
        int maxY = result.length - Tools.getBlankBottom(result);
        int maxX = result[0].length - Tools.getBlankRight(result);

        //判断边界
        if (relativeX+blankLeft<0 || relativeX+maxX>Config.getInstance().width_num){
            Log.d(TAG, String.format("relativeX=%d, blankLeft=%d, maxX=%d", relativeX, blankLeft, maxX));
            return false;
        }
        if (relativeY+maxY>Config.getInstance().heght_num || relativeY+blankTop<0){
            return false;
        }
        for (int i=blankTop; i<maxY; i++){
            for (int j=blankLeft; j<maxX; j++){
                if (result[i][j] != 0){
                    if (container[relativeY+i][relativeX+j] != 0){
                        return false;
                    }
                }
            }
        }
        return true;
    }
    private void fillTetrisToContainer(int relativeX, int relativeY, int[][] result) {

        int blankLeft = Tools.getBlankLeft(result);
        int maxY = result.length - Tools.getBlankBottom(result);
        int maxX = result[0].length - Tools.getBlankRight(result);
        int blankTop = Tools.getBlankTop(result);
//        speed = startSpeed;
        for (int i = blankTop; i < maxY; i++) {
            for (int j = blankLeft; j < maxX; j++) {
                container[relativeY + i][relativeX + j] += result[i][j];
            }
        }
        Tools.print(container);

    }

    public List<Integer> getFillTetrisLines(final Tetris tetris) {

        List<Integer> lines = new ArrayList<>();
        int relativeY = tetris.getRelativeY(Config.getInstance().getSideLength());
        int blankTop = Tools.getBlankTop(tetris.getMatrix());
        int maxY = tetris.getMatrix().length - Tools.getBlankBottom(tetris.getMatrix());
        for (int i = relativeY + blankTop; i < relativeY + maxY; i++) {
            int tetrisNum = 0;
            for (int j = 0; j < container[0].length; j++) {
                if (container[i][j] == 0) {
                    break;
                } else {
                    tetrisNum++;
                }
            }
            if (tetrisNum == container[0].length) {
                lines.add(i);
            }
        }
        return lines;
    }



    public boolean isGameOver(){
        for (int i=0; i<container[0].length; i++){
            if (container[0][i] != 0){
                return true;
            }
        }
        return false;
    }

    public int[][] getContainer() {
        return container;
    }

    public void setContainer(int[][] container) {
        this.container = container;
    }
}
